// Codigo unico de grupo: GPS3_14
// Integrante 1: Juan Manuel Gonzalez Garzon (200913667)

import java.io.*;
import java.text.DecimalFormat;
import java.util.Arrays;

public class lazyprof {

	public static void main(String[] args){
		try{

			//TODO Quitar al finalizar la impelemntacion.
			//PrintStream log = new PrintStream(new File("./data/outLazy.txt"));
			//System.setOut(log);

			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			String line = reader.readLine();  
			boolean primero=true;

			while (!line.equals("0 0"))
			{
				String resp = "";

				String[] nums = line.split(" ");
				int numEstudiantes=Integer.parseInt(nums[0]);
				int numTest=Integer.parseInt(nums[1]);

				Parcial[] parciales= new Parcial[numTest];

				for (int i = 0; i < numEstudiantes; i++) {
					String notasEstudiante=reader.readLine();
					String[] notas = notasEstudiante.split(" ");

					for (int j = 0; j < notas.length; j++) {
						if(parciales[j]==null)parciales[j]= new Parcial();
						parciales[j].agregarNota(Integer.parseInt(notas[j]));
					}

				}

				for (int i = 0; i < parciales.length; i++) {
					String[] rango = reader.readLine().split(" ");
					parciales[i].setMinimo(Integer.parseInt(rango[0]));	
					parciales[i].setMaximo(Integer.parseInt(rango[1]));	
				}

				try
				{
					double sinFormato=calcularMax(parciales);
					DecimalFormat dc = new DecimalFormat("#.##");
					resp=dc.format(sinFormato);
				}
				catch(Exception e){resp="0.00";}

				if(primero){System.out.print(resp);primero=false;}
				else System.out.print("\r\n"+resp);

				line = reader.readLine();
			}
			reader.close();
		}
		catch(IOException e){e.printStackTrace();}
	}

	private static double calcularMax(Parcial[] parciales) {

		double resp=0;
		Arrays.sort(parciales);
		for (int i = 0; i < parciales.length; i++) {
			if(i+1< parciales.length){
				parciales[i].setSiguiente(parciales[i+1]);
			}
		}
		if(parciales[0]!=null){
			resp=parciales[0].recursividadNivel(100);
		}
		return resp;
	}

	private static class Parcial implements Comparable<Parcial>{

		private double notaAcumulada;
		private double promedio;
		private int minimo;
		private int maximo;
		private int numeroDeEstudiantes;
		private Parcial siguiente;

		public Parcial(){
			notaAcumulada=0;
			minimo=0;
			maximo=0;
			numeroDeEstudiantes=0;
			siguiente=null;
		}

		public double recursividadNivel(int lol) {
			double resp=0;
			if(lol==0)
			{
				System.out.println("entro :"+promedio);
				resp=promedio;
			}
			else if(lol<0){
				resp=-1;
			}
			else if(lol>0)
			{
				System.out.println("fuu "+lol);
				if(siguiente!=null){
					double max=0;
					for (int i = maximo; i >= minimo; i--) {
						double este = siguiente.recursividadNivel(lol-i);
						if(este>max){
							resp=este;
							max=este;
						}
					}
				}
			}
			return resp;
		}

		public void setSiguiente(Parcial siguiente) {
			this.siguiente=siguiente;
		}

		public double getPromedio() {
			return promedio;
		}

		public void setMinimo(int minimo) {
			this.minimo = minimo;
		}
		public void setMaximo(int maximo) {
			this.maximo = maximo;
		}

		public void agregarNota(int notaEstudiante) {
			numeroDeEstudiantes++;
			notaAcumulada+=notaEstudiante;
			promedio=notaAcumulada/numeroDeEstudiantes;
		}

		@Override
		public int compareTo(Parcial o) {

			double diferencia = promedio-o.getPromedio();

			if(diferencia<0)diferencia=(-1);
			else if (diferencia>0) diferencia=1;

			return (int) diferencia;
		}
	}

}